package com.corpgovernment.common.config;

import com.alibaba.fastjson.JSON;
import com.corpgovernment.common.common.ContextUtils;
import com.corpgovernment.common.entity.Constan;
import com.corpgovernment.common.entity.LogToken;
import com.corpgovernment.common.helper.RequestHelper;
import feign.RequestInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: corpgovernment-common-logging
 * @description: mvc全局配置
 * @author: wubing
 * @create: 2019-06-10 15:38
 */
@Configuration
@Slf4j
public class WebMvcLogConfig implements WebMvcConfigurer {

    private static boolean isDefaultHandler(String handlerClassName) {
        return "org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler"
                .equalsIgnoreCase(handlerClassName);
    }


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        HandlerInterceptor interceptor = new HandlerInterceptor() {
            /**
             * 前置获取用户信息
             * @param request
             * @param response
             * @param handler
             * @return
             * @throws Exception
             */
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                if (isDefaultHandler(handler.getClass().getName())) {
                    return true;
                }
                if (RequestMethod.OPTIONS.name().equalsIgnoreCase(request.getMethod())) {
                    response.setStatus(HttpStatus.NO_CONTENT.value());
                    return false;
                }
                LogToken logToken = new LogToken();
                String serverIp = "";
                try {
                    serverIp = InetAddress.getLocalHost().getHostAddress();
                } catch (Exception ex) {
                }
                logToken.setServerIp(serverIp);
                logToken.setIp(RequestHelper.getClientIPAddress(request));
                logToken.setRawUrl(RequestHelper.getRawUrl(request));
                String param = RequestHelper.getRequestParams(request);
                if (!StringUtils.isEmpty(param)) {
                    Map<String, Object> paramMap = new HashMap<>();
                    try {
                        paramMap = JSON.parseObject(param, paramMap.getClass());
                    } catch (Exception e) {

                    }
                    if (paramMap != null) {
                        logToken.setPayType(paramMap.get("CorpPayType") != null ? paramMap.get("CorpPayType").toString() : "");
                        logToken.setGe(paramMap.get("GE") != null ? paramMap.get("GE").toString() : "");
                        logToken.setLanguage(paramMap.get("language") != null ? paramMap.get("language").toString() : "");
                        logToken.setSite(paramMap.get("site") != null ? paramMap.get("site").toString() : "");
                        logToken.setUserAgent(paramMap.get("pu") != null ? paramMap.get("pu").toString() : "");
                        logToken.setToken(paramMap.get("token") != null ? paramMap.get("token").toString() : "");
                    }
                }
                //如果请求参数中没找到token信息，从header中继续找token信息
                if (StringUtils.isEmpty(logToken.getToken())) {
                    Map<String, String> headers = RequestHelper.getAllHeaders(request);
                    if (headers.get("token") != null) {
                        logToken.setToken(headers.get("token"));
                    }
                }
                //如果请求参数中没找到token信息，从cookie中继续找token信息
                //TODO
                Cookie[] cookies = request.getCookies();
                //从请求头里面获取token
                if (!StringUtils.isEmpty(request.getHeader("token"))) {
                    logToken.setHeaderToken(request.getHeader("token"));
                }
                //从请求头获取source
                if (!StringUtils.isEmpty(request.getHeader("source"))) {
                    logToken.setSource(request.getHeader("source"));
                }
                //获取request header中request_id 达到日志串行化目的
                String traceId = request.getHeader(Constan.request_id);
                if (!StringUtils.isEmpty(traceId)) {
                    logToken.setRequestId(traceId);
                }
                //获取request header中HEADER_TOKEN 达到soa日志保留token目的
                String headerToken = request.getHeader(Constan.header_token);
                if (!StringUtils.isEmpty(headerToken)) {
                    logToken.setHeaderToken(headerToken);
                }
                ContextUtils.INSTANCE.set(logToken);
                return true;
            }

            @Override
            public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
	            ContextUtils.INSTANCE.remove();
            }
        };
        InterceptorRegistration registration = registry.addInterceptor(interceptor);
        //排除的路径
        registration.excludePathPatterns("/login");
        registration.excludePathPatterns("/logout");
        //将这个controller放行
        registration.excludePathPatterns("/error");
        //拦截全部
        registration.addPathPatterns("/**");
    }


    @Bean
    public RequestInterceptor addHeaderTrace() {
        RequestInterceptor requestInterceptor = requestTemplate -> {
            LogToken logToken = (LogToken) ContextUtils.INSTANCE.get();
            if (logToken != null && !StringUtils.isEmpty(logToken.getRequestId())) {
                String requestId = logToken.getRequestId();
                requestTemplate.header(Constan.request_id, requestId);
            }
            if (logToken != null && !StringUtils.isEmpty(logToken.getToken())) {
                String token = logToken.getToken();
                requestTemplate.header(Constan.header_token, token);
            }
        };
        return requestInterceptor;
    }
}